package org.jg.arkanoid.engine.collider;

import java.util.Collection;

import org.jg.arkanoid.gameobjects.Ball;
import org.jg.arkanoid.gameobjects.GameObject;

public class CollisionDetector 
{
	private static CollisionDetector colliderInstance;
	private Collection<GameObject> gameObjects;
	
	private int spaceXbound;
	private int spaceYbound;
	
	public static CollisionDetector getInstance()
	{
		if (colliderInstance != null)
			return colliderInstance;

		synchronized (CollisionDetector.class) 
		{
			colliderInstance = new CollisionDetector();
			return colliderInstance;
		}
	}
	
	private CollisionDetector() {}

	public void setGameObjects(Collection<GameObject> movingObjects)
	{
		this.gameObjects = movingObjects;
	}
	
	public Collection<GameObject> getMovingObjects()
	{
		return gameObjects;
	}
	
	public void setSpaceBounds(int xBound, int yBound)
	{
		spaceXbound = xBound;
		spaceYbound = yBound;
	}
	
	public boolean checkForCollisions()
	{
		boolean collisionHasHappened = false;
		
		GameObject[] objects =  gameObjects.toArray( new GameObject[0] );
		
		for(int i = 0; i<objects.length; i++ )
		{
			collisionHasHappened = ObjectCollider.doSpaceBoundsCollision(objects[i], spaceXbound, spaceYbound);
			
			if( !collisionHasHappened )
			{
				collisionHasHappened = doObjectCollision(objects[i], objects, i+1);
			}
		}
		
		return collisionHasHappened;
	}
	
	private boolean doObjectCollision(GameObject object, GameObject[] objects, int offsetIndex)
	{
		boolean collisionHasHappened = false;
		
		if(offsetIndex >= objects.length)
			return collisionHasHappened;
		
		for(int i = offsetIndex; i < objects.length; i++)
		{
			GameObject stumbleObject = objects[i];
			
			if(object == stumbleObject || !object.isCollidable() || !stumbleObject.isCollidable())
			{
				continue;
			}
			
			if(object instanceof Ball && stumbleObject instanceof Ball)
			{
				collisionHasHappened = ObjectCollider.doBallsCollision((Ball)object, (Ball)stumbleObject);
			}
			else if( object instanceof Ball )
			{
				collisionHasHappened = ObjectCollider.doBallToRectangularCollision((Ball)object, stumbleObject);
			}
		}
		
		return collisionHasHappened;
	}
}
